#ifndef SITE_H
#define SITE_H

#include <iostream>
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include <memory>
#include <os.h>
#include <htmlcxx/html/ParserDom.h>
#include "main.h"
#include "htpargs.h"
#include "config.h"

#define _C <<","<<
#define _S(v) "'" << v << "'"
#define STR(v) "'" << hs[v] << "'"
#define INT(v) hs(v)

#define _DOMAIN_SCORE  5000 // TODO
#define _MAX_SITE_LINKS 300 //_max_links

using namespace htmlcxx;
using namespace std;
class mysqlcls;


class wsite
{
public:
    wsite(const char* url, mysqlcls* db, mutex* m):_db(db),_m(m)
    {
        GLOGT( "enter site:" << url);
        _hargs.parse(url);

        _total_links=0;
        _max_links = _hargs("links") ? _hargs("links") : GCFG->_links;
        _depth_max = _hargs("mxd") ? _hargs("mxd") : GCFG->_depth;
        _reindex = _hargs("reindex");
    }
    virtual ~wsite(){
        GLOGT( "site done " << _site_id);
    }
    void _db_clean_unrefs();

    mysqlcls*               _db;
    mutex*                  _m;
    uint32_t                _z_id;
    uint32_t                _site_id;
    map<string, int32_t>    _scores;
    uint32_t                _total_links;
    uint32_t                _max_links;
    uint32_t                _depth_max;
    bool                    _reindex;
    htpargs                 _hargs;
};

template <typename T>
class ref_count
{
public:
    ref_count():_ptr(0),_prefs(0){

        AutoLock l(&_m);
        _prefs=new int32_t;
        *_prefs=0;
    }

    ref_count(T* pt):_ptr(0),_prefs(0)
    {
        AutoLock l(&_m);

        _prefs=new int32_t;
        (*_prefs)++;
        _ptr=pt;
    }
    ref_count(const ref_count& r): _ptr(r._ptr), _prefs(r._prefs)
    {
        AutoLock l(&_m);
        (*_prefs)++;
    }
    ref_count<T>& operator = ( ref_count& r)
    {
        if(this!=&r)
        {
            AutoLock l(&_m);
            /*
            if(--(*r._prefs) == 0)
            {
                delete _prefs;
                delete _ptr;
            }
            */

            _ptr = r._ptr;
            _prefs = r._prefs;
            ++(*_prefs);
        }
        return *this;
    }
    virtual ~ref_count()
    {
        if(--(*_prefs) == 0)
        {
            delete _prefs;
            delete _ptr;
        }
    }

    T& operator* ()
    {
        return *_ptr;
    }

    T* operator-> ()
    {
        return _ptr;
    }
    T* ptr(){return _ptr;} //debig only
private:
    T*          _ptr;
    int32_t*    _prefs;
    mutex       _m;
};



class uripage
{
    typedef enum _PAGE_ST
    {
        NEW_LINK,
        REFR_LINK,
        CHNG_LINK,
        PG_DONE,
        DB_LINK,
    } PAGE_ST;

public:
    uripage(ref_count<wsite> site, string& uri, const uripage* root=0);   // Parse

    void create(mysqlcls* db);

    ~uripage()
    {
    }

    bool operator==(const uripage& o)
    {
        return (_qry==o._qry &&  _path==o._path && _host==o._host);
    }

    bool _robots_omit();

    bool  _db_add_site();
    void db_remove();
    bool _moved();
    void _index(bool newsite=false);
    PAGE_ST _changed();
    void _parse_page();
    int  _db_update_link(bool update=false);
    int  _db_finalize_page();
    void _enqueue(string uri, const string& name, uint32_t sid, uint32_t dpth, int32_t parentid);
    void _add_links_from_dbpage();
    int32_t  _score(const char* tag)const;
    void _add_word(string word, int32_t score, bool entire, bool incontent);
    void _eval_htmlelement(tree<HTML::Node>& dom, tree<HTML::Node>::iterator& it, int32_t& score);


    ref_count<wsite>  _web_site;


    uint32_t    _level_down;
    uint32_t    _link_id;
    uint32_t    _parent_id;
    int         _bkls;
    bool        _deleted;
    int         _links_count;
    bool        _updated;
    int32_t     _accum;
    mysqlcls*   _p_dbase;

    string      _port, _qry, _path, _proto, _host, _uri;
    string      _hostname;
    string      _robots;
    string      _header;
    string      _content;
    string      _location;
    string      _mime;
    string      _date;
    string      _md5;
    string      _title;

    string      _desc;
    string      _link_name;
    string     _compressed;
    map<string,int> _scores;

};  // uri



#endif // SITE_H
